package com.bys.admin.system.service.impl;

import cn.hutool.jwt.JWT;
import com.bys.redis.RedisCache;
import com.bys.admin.system.dto.LoginUser;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.bys.constant.CommonConstant.LOGIN_USER_KEY;

/**
 * token验证处理
 */
@Component
@Slf4j
public class TokenService {
    @Value("${token.secret}")
    private String secret;

    @Value("${token.header}")
    private String header;

    @Value("${token.expireTime}")
    private Integer  expireTime;

    @Resource
    private RedisCache<LoginUser> redisCache;


    public String createToken(LoginUser loginUser) {
        Map<String,Object> params = new HashMap<>();
        params.put("login_user_key",loginUser.getId());
        refreshToken(loginUser);
        long expirationMs = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(expireTime);
        return  JWT.create()
                .setPayload(LOGIN_USER_KEY,loginUser.getId()).setExpiresAt((new Date(expirationMs))).setKey(secret.getBytes(StandardCharsets.UTF_8)).sign();
    }

    private void refreshToken(LoginUser loginUser) {
        loginUser.setLoginTime(LocalDateTime.now());
        loginUser.setExpireTime(loginUser.getLoginTime().minusMinutes(expireTime));
        Long id = loginUser.getId();
        redisCache.setCacheObject(id.toString(), loginUser, expireTime, TimeUnit.MINUTES);
    }

    public LoginUser getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = request.getHeader(header);
        if (StringUtils.isNotBlank(token))
        {
            try
            {
                JWT parsedJwt = JWT.of(token);
                // 解析对应的权限以及用户信息
                boolean isValid = parsedJwt.setKey(secret.getBytes()).verify();
                if(isValid){
                    String userId = parsedJwt.getPayload(LOGIN_USER_KEY).toString();
                    return redisCache.getCacheObject(userId);
                }

            }
            catch (Exception e)
            {
                log.error("获取用户信息异常'{}'", e.getMessage());
            }
        }
        return null;
    }
    /**
     * 验证令牌有效期，相差不足20分钟，自动刷新缓存
     *
     */
    public void verifyToken(LoginUser loginUser) {
        LocalDateTime expireTime = loginUser.getExpireTime();
        LocalDateTime now = LocalDateTime.now();
        if (expireTime.isAfter(now))
        {
            refreshToken(loginUser);
        }

    }
}
